package com.wuchaooooo.service.zjutsds.service;

import java.util.ArrayList;
import java.util.Collections;
import java.util.Comparator;
import java.util.Date;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

import javax.annotation.Resource;

import org.apache.commons.lang.StringUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import com.wuchaooooo.service.zjutsds.dao.CareerDAO;
import com.wuchaooooo.service.zjutsds.dao.MajorDAO;
import com.wuchaooooo.service.zjutsds.dao.QuestionDAO;
import com.wuchaooooo.service.zjutsds.dao.UserAnswerDAO;
import com.wuchaooooo.service.zjutsds.dao.UserDAO;
import com.wuchaooooo.service.zjutsds.pojo.po.PCareer;
import com.wuchaooooo.service.zjutsds.pojo.po.PMajor;
import com.wuchaooooo.service.zjutsds.pojo.po.PQuestion;
import com.wuchaooooo.service.zjutsds.pojo.po.PUser;
import com.wuchaooooo.service.zjutsds.pojo.po.PUserAnswer;
import com.wuchaooooo.service.zjutsds.pojo.vo.VMajor;
import com.wuchaooooo.service.zjutsds.pojo.vo.VQuestion;
import com.wuchaooooo.service.zjutsds.pojo.vo.VResult;
import com.wuchaooooo.service.zjutsds.pojo.vo.VUser;
import com.wuchaooooo.service.zjutsds.utils.CacheContext;
import com.wuchaooooo.service.zjutsds.utils.CommonUtils;

/**
 * Created by wuchaooooo on 08/06/2017.
 */
@Service
public class QuestionsService {
	@Autowired
	private UserDAO userDAO;
	@Autowired
	private CareerDAO careerDAO;
	@Autowired
	private MajorDAO majorDAO;
	@Autowired
	private QuestionDAO questionDAO;
	@Autowired
	private UserAnswerDAO userAnswerDAO;
	@Resource
	private CacheContext<Map<String, List<VQuestion>>> questionCacheContext;

	private final Logger logger = LoggerFactory.getLogger(QuestionsService.class);

	/**
	 * 提交答案，并取得计算结果
	 * 
	 * @param vResult
	 * @param vUser
	 * @return
	 */
	public boolean postResult(VResult vResult, VUser vUser) {
		// 保存题目答案
		this.saveQuestion(vResult, vUser.getId());
		// 计算性格
		List<String> charList = getCharList(this.calcValue(vResult));
		// 保存用户性格
		PUser pUser = new PUser();
		pUser.setCharacter(StringUtils.join(charList, ","));
		pUser.setGmtCreateTopic(new Date());
		pUser.setId(vUser.getId());
		userDAO.saveResult(pUser);
		return true;
	}

	/**
	 * 取得计算结果
	 * @param vResult
	 * @param vUser
	 * @return
	 */
	public Map<String, Object> calcAndRecom(VResult vResult, VUser vUser) {
		Map<String, Object> result = new HashMap<String, Object>();
		// 计算性格
		Map<String, String> calcResult = this.calcValue(vResult);
		result.put("result", calcResult);
		List<String> charList = this.getCharList(calcResult);
		// 生成专业
		List<PCareer> careerlist = this.getRecom(vUser, charList);
		result.put("careerlist", careerlist);
		return result;
	}

	/**
	 * 计算结果
	 * @param vResult
	 * @return
	 */
	private Map<String, String> calcValue(VResult vResult) {
		Map<String, String> result = new HashMap<String, String>();
		Map<String, List<VQuestion>> map = this.listQuestion();

		List<VQuestion> capList = map.get("capability");
		List<VQuestion> hobbyList = map.get("hobby");

		for (int i = 0; i < capList.size(); i++) {
			VQuestion question = capList.get(i);
			// 能力
			Integer value = CommonUtils.getFieldValueByFieldName("qc" + (i + 1), vResult);
			String key = question.getIndex() + "_" + question.getType();
			if (result.containsKey(key)) {
				result.put(key, String.valueOf(Integer.valueOf(result.get(key)) + value * 2));
			} else {
				result.put(key, String.valueOf(value * 2));
			}
		}

		for (int i = 0; i < hobbyList.size(); i++) {
			VQuestion question = hobbyList.get(i);
			// 能力
			Integer value = CommonUtils.getFieldValueByFieldName("qh" + (i + 1), vResult);
			String key = question.getIndex() + "_" + question.getType();
			if (result.containsKey(key)) {
				result.put(key, String.valueOf(Integer.valueOf(result.get(key)) + value));
			} else {
				result.put(key, String.valueOf(value));
			}
		}

		return result;
	}

	/**
	 * 取得最高三个性格
	 * @param vResult
	 * @param result
	 * @return
	 */
	private List<String> getCharList(Map<String, String> calcResult) {
		List<Map.Entry<String, String>> list = new ArrayList<>(calcResult.entrySet());
		Collections.sort(list, new Comparator<Map.Entry<String, String>>() {
			@Override
			public int compare(Map.Entry<String, String> o1, Map.Entry<String, String> o2) {
				// 按照value值，从大到小排序

				return o2.getValue().compareTo(o1.getValue());
			}
		});

		List<String> keyList = new ArrayList<String>();
		for (Map.Entry<String, String> s : list) {
			if (s.getKey().contains("H")) {
				keyList.add(s.getKey().replace("H_", ""));
			}
			if (keyList.size() >= 3) {
				break;
			}
		}
		return keyList;

	}

	/**
	 * 取得推荐专业
	 * @param vUser
	 * @param charList
	 * @return
	 */
	private List<PCareer> getRecom(VUser vUser, List<String> charList) {
		// 生成专业
		PCareer pCareer = new PCareer();
		pCareer.setGender(vUser.getGender());
		pCareer.setSubject(vUser.getSubject());
		pCareer.setCourse(vUser.getAdvMajor() + "," + vUser.getAdvSub());
		pCareer.setCharacter(StringUtils.join(charList, ","));
		List<PCareer> careerlist = careerDAO.getCareer1(pCareer);
		if (careerlist.size() < 18) {
			logger.info("careerlist size is : " + careerlist.size());
			careerlist = careerDAO.getCareer2(pCareer);
		}
		return careerlist;
	}

	/**
	 * 
	 * @param vResult
	 * @param userid
	 * @return
	 */
	public int saveQuestion(VResult vResult, int userid) {
		PUserAnswer ua = new PUserAnswer();
		BeanUtils.copyProperties(vResult, ua);
		ua.setUserid(userid);
		return userAnswerDAO.saveQuestionByUserId(ua);
	}

	/**
	 * 
	 * @param userid
	 * @return
	 */
	public PUserAnswer getQuestion(int userid) {
		return userAnswerDAO.getQuestionByUserId(userid);
	}

	public List<VMajor> listMajor(String sdsName) {
		List<String> sdsNameList = equalSdsName(sdsName);
		List<PMajor> pMajorList = new ArrayList<>();
		for (int i = 0; i < sdsNameList.size(); i++) {
			List<PMajor> pMajorList1 = majorDAO.listMajor(sdsNameList.get(i));
			if (pMajorList1 != null) {
				for (PMajor pMajor : pMajorList1) {
					pMajorList.add(pMajor);
				}
			}
		}
		List<VMajor> vMajorList = new ArrayList<>();
		if (pMajorList != null) {
			for (PMajor pMajor : pMajorList) {
				VMajor vMajor = new VMajor();
				BeanUtils.copyProperties(pMajor, vMajor);
				vMajorList.add(vMajor);
			}
		}
		return vMajorList;
	}

	/**
	 * 取得所有题目
	 * @return
	 */
	public Map<String, List<VQuestion>> listQuestion() {

		Map<String, List<VQuestion>> result = questionCacheContext.get("question");
		if (result != null) {
			logger.info("get from cache... {}", "question");
			return result;
		}

		List<PQuestion> pQuestionList = questionDAO.getQuestion();
		Map<String, List<VQuestion>> map = new HashMap<String, List<VQuestion>>();
		List<VQuestion> vQuestionList1 = new ArrayList<VQuestion>();
		List<VQuestion> vQuestionList2 = new ArrayList<VQuestion>();
		for (PQuestion pQuestion : pQuestionList) {
			VQuestion vQuestion = new VQuestion();
			vQuestion.setId(pQuestion.getId());
			//
			vQuestion.setQuestion(pQuestion.getQuestion());
			vQuestion.setType(pQuestion.getType());
			switch (pQuestion.getType()) {
			case "T":
				vQuestion.setTypeName("技术");
				break;
			case "N":
				vQuestion.setTypeName("自然");
				break;
			case "A":
				vQuestion.setTypeName("艺术");
				break;
			case "C":
				vQuestion.setTypeName("常规");
				break;
			case "R":
				vQuestion.setTypeName("研究");
				break;
			case "E":
				vQuestion.setTypeName("经济");
				break;
			case "S":
				vQuestion.setTypeName("社会");
				break;
			}
			// 能力
			vQuestion.setIndex(pQuestion.getIndex());
			if ("C".equals(pQuestion.getIndex())) {
				vQuestion.setIndexName("能力");
				vQuestionList2.add(vQuestion);
			} else {
				vQuestion.setIndexName("兴趣");
				vQuestionList1.add(vQuestion);
			}
		}
		map.put("capability", vQuestionList2);
		map.put("hobby", vQuestionList1);
		questionCacheContext.addOrUpdateCache("question", map);
		return map;
	}

	// 有些sdsName没有对应的学校专业，所以等同于其他的sdsName进行学校专业的查找
	private List<String> equalSdsName(String sdsName) {
		List<String> list = new ArrayList<>();
		if (sdsName.equals("RAC")) {
			list.add("RAI");
			return list;
		} else if (sdsName.equals("RAE")) {
			list.add("RAI");
			return list;
		} else if (sdsName.equals("RAS")) {
			list.add("RAI");
			return list;
		} else if (sdsName.equals("RSA")) {
			list.add("SAI");
			list.add("RSI");
			return list;
		} else if (sdsName.equals("RSC")) {
			list.add("RCS");
			list.add("RSE");
			return list;
		} else if (sdsName.equals("REA")) {
			list.add("RES");
			list.add("REI");
			return list;
		} else if (sdsName.equals("RCA")) {
			list.add("RAI");
			list.add("RCI");
			return list;
		} else if (sdsName.equals("CRA")) {
			list.add("RAI");
			list.add("CRS");
			return list;
		} else if (sdsName.equals("CIA")) {
			list.add("CIS");
			list.add("IAS");
			return list;
		} else if (sdsName.equals("CSI")) {
			list.add("CIS");
			return list;
		} else if (sdsName.equals("CEA")) {
			list.add("CES");
			return list;
		} else if (sdsName.equals("CAR")) {
			list.add("RAI");
			list.add("CRS");
			return list;
		} else if (sdsName.equals("CAE")) {
			list.add("CES");
			return list;
		} else if (sdsName.equals("CAS")) {
			list.add("CSA");
			return list;
		} else if (sdsName.equals("CAI")) {
			list.add("AIR");
			return list;
		} else if (sdsName.equals("ECR")) {
			list.add("ERC");
			return list;
		} else if (sdsName.equals("ECA")) {
			list.add("ECS");
			list.add("EAR");
			return list;
		} else if (sdsName.equals("ERA")) {
			list.add("EAR");
			return list;
		} else if (sdsName.equals("EIA")) {
			list.add("IES");
			list.add("EIS");
			return list;
		} else if (sdsName.equals("EAC")) {
			list.add("ECS");
			list.add("EAR");
			return list;
		} else if (sdsName.equals("EAI")) {
			list.add("EAR");
			list.add("IES");
			list.add("EIS");
			return list;
		} else if (sdsName.equals("SCR")) {
			list.add("SRC");
			return list;
		} else if (sdsName.equals("SCA")) {
			list.add("AIE");
			list.add("AIR");
			return list;
		} else if (sdsName.equals("SCI")) {
			list.add("SIC");
			return list;
		} else if (sdsName.equals("SRA")) {
			list.add("SAC");
			return list;
		} else if (sdsName.equals("SAR")) {
			list.add("SAC");
			return list;
		} else if (sdsName.equals("ASR")) {
			list.add("ASE");
			list.add("ASI");
			return list;
		} else if (sdsName.equals("ASC")) {
			list.add("ASE");
			list.add("ASI");
			return list;
		} else if (sdsName.equals("AEC")) {
			list.add("AER");
			return list;
		} else if (sdsName.equals("AIC")) {
			list.add("AIR");
			return list;
		} else if (sdsName.equals("ARC")) {
			list.add("AER");
			return list;
		} else if (sdsName.equals("ARE")) {
			list.add("AER");
			return list;
		} else if (sdsName.equals("ARS")) {
			list.add("AER");
			return list;
		} else if (sdsName.equals("ARI")) {
			list.add("AIR");
			return list;
		} else if (sdsName.equals("ACR")) {
			list.add("AER");
			return list;
		} else if (sdsName.equals("ACE")) {
			list.add("AER");
			return list;
		} else if (sdsName.equals("ACS")) {
			list.add("ASE");
			list.add("ASI");
			return list;
		} else if (sdsName.equals("ACI")) {
			list.add("AIR");
			return list;
		} else if (sdsName.equals("IAC")) {
			list.add("IAR");
			return list;
		} else if (sdsName.equals("IAE")) {
			list.add("IAS");
			return list;
		} else if (sdsName.equals("IER")) {
			list.add("IRE");
			return list;
		} else if (sdsName.equals("IEA")) {
			list.add("IAS");
			return list;
		} else if (sdsName.equals("ICE")) {
			list.add("IEC");
			return list;
		} else if (sdsName.equals("ICS")) {
			list.add("ISC");
			return list;
		} else if (sdsName.equals("ICA")) {
			list.add("IAR");
			return list;
		} else {
			list.add(sdsName);
			return list;
		}
	}

	/*
	 * //获取前端的问卷答案，计算出各问题回答"是"的题数 public Map<String, Integer>
	 * getNumOfType(VResult vResult) { Map<String, Integer> map = new
	 * TreeMap<>(); //R现实型题目 回答"是"的个数 int r = vResult.getQ1() + vResult.getQ7()
	 * + vResult.getQ13() + vResult.getQ19() + vResult.getQ25() +
	 * vResult.getQ31() + vResult.getQ37() + vResult.getQ43() + vResult.getQ49()
	 * + vResult.getQ55(); //C常规型题目 回答"是"的个数 int c = vResult.getQ2() +
	 * vResult.getQ8() + vResult.getQ14() + vResult.getQ20() + vResult.getQ26()
	 * + vResult.getQ32() + vResult.getQ38() + vResult.getQ44() +
	 * vResult.getQ50() + vResult.getQ56(); //E企业型题目 回答"是"的个数 int e =
	 * vResult.getQ3() + vResult.getQ9() + vResult.getQ15() + vResult.getQ21() +
	 * vResult.getQ27() + vResult.getQ33() + vResult.getQ39() + vResult.getQ45()
	 * + vResult.getQ51() + vResult.getQ57(); //S社会型题目 回答"是"的个数 int s =
	 * vResult.getQ4() + vResult.getQ10() + vResult.getQ16() + vResult.getQ22()
	 * + vResult.getQ28() + vResult.getQ34() + vResult.getQ40() +
	 * vResult.getQ46() + vResult.getQ52() + vResult.getQ58(); //A艺术型题目 回答"是"的个数
	 * int a = vResult.getQ5() + vResult.getQ11() + vResult.getQ17() +
	 * vResult.getQ23() + vResult.getQ29() + vResult.getQ35() + vResult.getQ41()
	 * + vResult.getQ47() + vResult.getQ53() + vResult.getQ59(); //I研究型题目
	 * 回答"是"的个数 int i = vResult.getQ6() + vResult.getQ12() + vResult.getQ18() +
	 * vResult.getQ24() + vResult.getQ30() + vResult.getQ36() + vResult.getQ42()
	 * + vResult.getQ48() + vResult.getQ54() + vResult.getQ60(); map.put("R",
	 * r); map.put("C", c); map.put("E", e); map.put("S", s); map.put("A", a);
	 * map.put("I", i); return map; }
	 */

	private List<Map.Entry<String, Integer>> sort(Map<String, Integer> map) {
		// 这里将map.entrySet()转换成list
		List<Map.Entry<String, Integer>> list = new ArrayList<Map.Entry<String, Integer>>(
				map.entrySet());
		// 然后通过比较器来实现排序
		Collections.sort(list, new Comparator<Map.Entry<String, Integer>>() {
			// 降序排序
			@Override
			public int compare(Map.Entry<String, Integer> o1, Map.Entry<String, Integer> o2) {
				return -o1.getValue().compareTo(o2.getValue());
			}

		});
		return list;
	}

}
